<!DOCTYPE html>
<html lang="zh-cn">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">




<title>HTTP权威指南 | Miles`s</title>

<link rel="stylesheet" href="https://mada.gitee.io/notes//css/styles.css">

<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.2.0/css/all.css" 
integrity="sha384-hWVjflwFxL6sNzntih27bfxkr27PmbbK/iSvJ+a4+0owXq79v+lsFkW54bOGbiDQ" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.3.1.js" integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60=" crossorigin="anonymous"></script>


<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/zenburn.min.css" crossorigin="anonymous" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js" integrity="sha256-/BfiIkHlHoVihZdc6TFuj7MmJ0TWcWsMXkeDFwhi0zw=" crossorigin="anonymous"></script>
<script>hljs.initHighlightingOnLoad();</script>
<script src="https://mada.gitee.io/notes//js/highlight.js"></script>






<div class="container">
    <nav class="navbar level">
      <div class="navbar-brand">
          <a class="nav-item" href="https://mada.gitee.io/notes/"><h1 class="title is-3">Miles`s</h1></a>
      </div>           
      <div class="navbar-menu has-text-centered is-active">
          <div class="navbar-end is-centered">
              
           </div>
      </div>
    </nav>
  </div>
<div class="container">
  <h2 class="subtitle is-6">December 5, 2016</h2>
  <h1 class="subtitle is-size-4-mobile is-size-3-desktop">HTTP权威指南</h1>
  <div class="content">
    

<p>《HTTP权威指南》读书笔记</p>

<h2 id="第一章-http概述">第一章 HTTP概述</h2>

<p><strong>第一章介绍内容：</strong></p>

<ul>
<li>Web客户端与服务器是如何通信的</li>
<li>资源来自何方</li>
<li>Web事务是怎样工作的</li>
<li>HTTP通信所使用的报文格式</li>
<li>底层TCP网络传输</li>
<li>不同的HTTP协议</li>
<li>因特网上安装的大量HTTP架构组件中的一部分。</li>
</ul>

<h3 id="1-1-http-因特网的多媒体信使">1.1 HTTP－－因特网的多媒体信使</h3>

<p>HTTP可以从遍布全世界的Web服务器上将这些信息块迅速，便捷，可靠地搬迁到人们桌面上的Web浏览器上。</p>

<h3 id="1-2-web客户端和服务器">1.2 Web客户端和服务器</h3>

<p>Web内容都是存储在Web服务器上的。Web服务器所使用的是HTTP协议，因此经常会被称为HTTP服务器。这些HTTP服务器存储了因特网中的数据，如果HTTP客户端发出请求的话，他们会提供数据。</p>

<p><img src="http-customer-server.png" alt="customer server client" /></p>

<h3 id="1-3-资源">1.3 资源</h3>

<p>Web服务器是Web资源的宿主。</p>

<p>资源不一定非得是静态文件，资源可以是根据需要生成内容的软件程序。</p>

<p>总之，所有类型的内容来源都是资源。</p>

<h4 id="1-3-1-媒体类型">1.3.1 媒体类型</h4>

<p>因特网上有数千种不同的数据类型，HTTP给每种痛过Web传输的对象打上了名为<code>MIME</code>（Multipurpose Internet Mail Extension,多用途因特网邮件扩展）类型的数据格式标签。最初来自电子邮件系统。</p>

<p>当Web浏览器从服务器中取回一个对象时，会去查看相关的MIME类型，看看它是否知道应该如何处理这个对象。</p>

<p><strong>MIME</strong>类型是一种文本标记，表示一种主要的对象类型和一个特定的子类型，中间由一条斜杆来分割。</p>

<ul>
<li>HTML格式的文本文档由<code>text/html</code>类型来标记</li>
<li>普通的ASCII文本文档由<code>text/plain</code>类型来标记</li>
<li>JPEG格式的图片为<code>image／jpeg</code>类型。</li>
<li>GIF格式的图片为<code>image/gif</code>类型</li>
</ul>

<h4 id="1-3-2-uri">1.3.2 URI</h4>

<p>每个Web服务器资源都有一个名字，这样客户端就可以说明它们刚兴趣的资源是什么了。服务器资源名称称为<code>统一资源标识符(Uniform Resource Identifier, URI)</code>。URI就像因特网上的邮政地址一样，在世界范围内唯一标示并定位信息资源。</p>

<p>URI有两种形式，分别称为URL和URN</p>

<h4 id="1-3-3-url">1.3.3 URL</h4>

<p><code>统一资源定位符（URL）</code>是资源标识符最常见的形式。描述了一台特定服务器上某资源的特定位置。</p>

<p>它们可以明确说明如何从一个精确、固定的位置获取资源。</p>

<p><img src="url.png" alt="url" /></p>

<p>大部分URL都遵循一种标准格式，这种格式包含三个部分。</p>

<ul>
<li>URL的第一部分被称为<code>方案（scheme）</code>，说明了访问资源所使用的协议类型。这部分通常就是HTTP协议（http://）。</li>
<li>第二部分给出了服务器的因特网地址。</li>
<li>其余部分指定了Web服务器上的某个资源。</li>
</ul>

<p>现在，几乎所有的URI都是URL。</p>

<h4 id="1-3-4-urn">1.3.4 URN</h4>

<p>URI的第二种形式就是<code>统一资源名（URN）</code>。URN是作为特定内容的唯一名称使用的，与目前的资源所在地无关。使用与位置无关的URN，就可以将资源四处搬移。通过URN，还可以用用一个名字通过多种网络访问协议访问资源。</p>

<p>仍然处于试验阶段，还未大范围使用。</p>

<h3 id="1-4-事务">1.4 事务</h3>

<p>一个HTTP事务由一条（从客户端发往服务器的）请求命令和一个（从服务器发回客户端的）响应结果组成。</p>

<p>这种通信是通过名为HTTP报文（HTTP message）的格式化数据块进行的。</p>

<p><img src="http-message.png" alt="http message" /></p>

<h4 id="1-4-1-方法">1.4.1 方法</h4>

<p>HTTP支持几种不同的请求命令，这些命令被称为<code>HTTP方法</code>。每条HTTP请求报文都包含一个方法。这个方法会告诉浏览器要执行什么动作（获取一个Web页面，运行一个网关程序，删除一个文件等）。</p>

<p>一些常用的HTTP方法：</p>

<p><img src="http-methods.png" alt="http message" /></p>

<h4 id="1-4-2-状态码">1.4.2 状态码</h4>

<p>每条HTTP响应报文返回时都会携带一个状态码。状态码是一个三位数字的代码，告知客户端请求是否成功，活着是否需要采取其它动作。</p>

<p><img src="http-state.png" alt="http state" /></p>

<h4 id="1-4-3-web页面中可以包含多个对象">1.4.3 Web页面中可以包含多个对象</h4>

<p>通常一个“Web页面”并不是单个资源，而是一组资源的集合。</p>

<h3 id="1-5-报文">1.5 报文</h3>

<p>HTTP报文是由一行一行的简单字符串组成的。
都是纯文本，不是二进制代码，所以人们可以很方便地对其进行读写。</p>

<p><strong>请求报文</strong>（request message）：从Web客户端发往Web服务器。
<strong>响应报文</strong>（response message）：从服务器发往客户端。</p>

<p>报文包括三个部分：</p>

<ul>
<li><strong>起始行</strong>：
报文的第一行就是起始行，在请求报文中用来说明要做些什么，在响应报文中说明出现了什么情况。</li>
<li><strong>首部字段</strong>：
起始行后面有零个或多个首部字段。每个字段都包含一个名字和一个值，为了便于解析，两者之间冒号来分隔。首部以一个空行结束。</li>
<li><strong>主体</strong>：
空行之后就是可选的报文主体了，其中包含了所有类型的数据。
起始行和首部都是文本形式且都是结构化的，而主体则不是，主体中包含任意的二进制数据（图片，视频，音频，软件程序等）。当然也包括文本。</li>
</ul>

<p><img src="http-message2.png" alt="http message2" /></p>

<h3 id="1-6-连接">1.6 连接</h3>

<p>报文通过传输控制协议（Transmission Control Protocol， TCP）连接从一个地方搬移到另一个地方去。</p>

<h4 id="1-6-1-tcp-ip">1.6.1 TCP/IP</h4>

<p>HTTP是个应用层协议。无需操心网络通信的具体细节，它把联网的细节都交给了通用、可靠的因特网传输协议TCP/IP。</p>

<p>TCP提供了：</p>

<ul>
<li>无差错的数据传输</li>
<li>按序传输（数据总是会按照发送的顺序到达）</li>
<li>未分段的数据流（可以在任意时刻以任意尺寸将数据发送出去）</li>
</ul>

<p>TCP/IP是全世界的计算机和网络设备常用的层次化分组交换网络协议集。TCP/IP隐藏了各种网络和硬件的特点及弱点，使各种类型的计算机和网络都能够进行可靠地通信。</p>

<p>只要建立了TCP连接，客户端和服务器之间的报文交换就不会丢失、不会被破坏、也不会在接收时出现错序了。</p>

<p>HTTP协议位于TCP的上层。HTTP使用TCP来传输其报文数据。</p>

<p><img src="tcp-ip.png" alt="tcp ip" /></p>

<h4 id="1-6-2-连接-ip地址及端口号">1.6.2 连接、IP地址及端口号</h4>

<p>在TCP中，你需要知道服务器IP地址，以及与服务器上运行的特定软件相关的TCP端口号。</p>

<p>通过URL获取HTTP服务器的IP地址和端口号。</p>

<p><img src="http-connetc.png" alt="http connect" /></p>

<h3 id="1-8-web的结构组件">1.8 Web的结构组件</h3>

<ul>
<li>代理</li>
<li>缓存</li>
<li>网关</li>
<li>隧道</li>
<li>Agent代理</li>
</ul>

<h4 id="1-8-1-代理">1.8.1 代理</h4>

<p>Web安全，应用集成以及性能优化的重要组成模块。</p>

<p>代理位于客户端和服务器之间，接收所有客户端的HTTP请求，并将这些请求转发给服务器（可能会对请求进行修改之后转发）。对用户来说，这些应用程序就是一个代理，代表用户访问服务器。</p>

<p><img src="http_proxy.png" alt="http proxy" /></p>

<h4 id="1-8-2-缓存">1.8.2 缓存</h4>

<p>Web缓存（Web cache）或代理缓存（proxy cache）是一种特殊的HTTP代理服务器，可以将经过代理传送的常用文档复制保存起来。下一个请求同一文档的客户端就可以享受缓存的私有副本所提供的服务了。</p>

<p><img src="http-cache.png" alt="http cache" /></p>

<p>客户端从附近的缓存下载文档会比远程Web服务器下载快得多。HTTP定义了很多功能，使得缓存更加高效，并规范了文档的新鲜度和缓存内容的隐私性。</p>

<h4 id="1-8-3-网关">1.8.3 网关</h4>

<p><strong>Gateway</strong>
一种特殊的服务器，作为其它服务器的中间实体使用。通常用于将HTTP流量转换成其它的协议。
网关接收请求时就好像自己是资源的源端服务器一样。
客户端可能并不知道自己正在与一个网关进行通信。</p>

<p>如：一个HTTP/FTP网关会通过HTTP请求接收对FTP URI的请求，但通过FTP协议来获取文档，得到的文档会被封装成一条HTTP报文，发送给客户单。</p>

<p><img src="http-gateway.png" alt="http gateway" /></p>

<h4 id="1-8-4-隧道">1.8.4 隧道</h4>

<p>隧道（tunnel）是建立起来之后，就会在两条连接之间对原始数据进行盲转发HTTP应用程序。
通常用来在一条或多条HTTP连接上发非HTTP数据，转发时不会窥探数据。</p>

<p>HTTP隧道的一种常见用途是通过HTTP连接承载加密的安全套接字层（SSL，Secure Sockets Layer）流量，这样SSL流量就可以穿过只允许Web流量通过的防火墙了。</p>

<p><img src="http-tunnel.png" alt="http tunnel" /></p>

<h4 id="1-8-5-agent-代理">1.8.5 Agent 代理</h4>

<p>用户Agent代理：代表用户发起HTTP请求的客户端程序。</p>

<p>所有发布Web请求的应用程序都是HTTP Agent代理。
比如Web浏览器。</p>

<h2 id="第二章-url与资源">第二章 URL与资源</h2>

<p>内容：</p>

<ul>
<li>URL语法</li>
<li>很多客户端支持URL快捷方式，包括相对URL和自动扩展URL</li>
<li>URL编码和字符规则</li>
<li>支持各种因特网信息系统的常见URL方案</li>
<li>URL的未来，包括URN－－这种框架可以在对象从一处搬移到另一处时，保持稳定的访问名称。</li>
</ul>

<h3 id="2-1-浏览因特网资源">2.1 浏览因特网资源</h3>

<p>URL分以下三个部分：</p>

<ul>
<li>URL方案（scheme）。告知Web客户端怎样访问资源。如HTTP协议</li>
<li>服务器位置。如<code>www.baidu.com</code></li>
<li>资源路径（/search/index.html）。说明的是服务器上哪个特定的资源。</li>
</ul>

<p><img src="http-url.png" alt="http url" /></p>

<h3 id="2-2-url的语法">2.2 URL的语法</h3>

<p>大多数URL方案的URL语法都建立在这9个部分构成的通用格式上：</p>

<p><code>&lt;scheme&gt;://&lt;user&gt;:&lt;password&gt;@&lt;host&gt;:&lt;port&gt;/&lt;path&gt;;&lt;params&gt;?&lt;query&gt;#&lt;frag&gt;</code></p>

<p>几乎没有哪个URL中包含了所有这些组件。最重要的3个部分是<code>方案（scheme）</code>、<code>主机（host）</code>、<code>路径（path）</code>。</p>

<p><img src="url-part.png" alt="url part" /></p>

<h4 id="2-2-1-方案-使用什么协议">2.2.1 方案－－使用什么协议</h4>

<p>方案实际上规定如何防蚊指定资源的主要标识符，它会告诉负责解析URL的应用程序该使用什么协议。</p>

<p>必须以一个字母符号开头，由第一个<code>“：”</code>符号将其与URL的其余部分分隔开来。</p>

<h4 id="2-2-2-主机与端口">2.2.2 主机与端口</h4>

<p>主机组件标示了因特网上能够访问资源的宿主机器。
端口标示了服务器正在监听的网络端口</p>

<h4 id="2-2-3-用户名和密码">2.2.3 用户名和密码</h4>

<p><code>ftp://host/path</code>
<code>ftp://name@host/path</code>
<code>ftp://name:password@host/path</code></p>

<h4 id="2-2-4-路径">2.2.4 路径</h4>

<h4 id="2-2-5-参数">2.2.5 参数</h4>

<p><code>ftp://host/path;type=d</code></p>

<p>参数名为 type，值为 d。</p>

<h4 id="2-2-6-查询字符串">2.2.6 查询字符串</h4>

<p>问好右边的内容是新出现的。这部分被称为查询（query）组件。</p>

<h4 id="2-2-7-片段">2.2.7 片段</h4>

<p>支持使用片段（flag）组件来标示一个资源内部的片段。比如，URL可以指向HTML文档中一个特定的图片或小节。</p>

<p><code>＃</code>号后面接内容。</p>

<p>对于HTTP服务器通常只处理整个对象，而不是对象的片段，客户端不能将片段传给服务器。浏览器从服务器获得了整个资源之后，会根据片段来显示你感兴趣的那部分资源。</p>

<h3 id="2-3-url快捷方式">2.3 URL快捷方式</h3>

<h4 id="相对url">相对URL</h4>

<p>URL有两种方式：<code>绝对的</code>和<code>相对的</code>。</p>

<p>如果使用相对URL，就可以在搬移一组文档的同事，仍然可以保持链接的有效性，因为相对URL都是相对于新基础进行解释的。</p>

<h4 id="自动扩展url">自动扩展URL</h4>

<p>浏览器自动扩展，用户不需要输入完整的URL。</p>

<ul>
<li>主机名扩展</li>
<li>历史扩展</li>
</ul>

<h3 id="2-4-各种令人头疼的字符">2.4 各种令人头疼的字符</h3>

<p>URL是可移植的（portable）。它要统一地命名因特网上的所有资源，这也就意味着要通过各种不同的协议来传送这些资源。</p>

<p>安全传输意味着URL的传输不能丢失信息。</p>

<p>除了希望URL可以被所有因特网协议惊喜传送之外，设计者们还希望URL也可供人们阅读。</p>

<p>URL还得是完整的，因此，需要有一种转义机制，能将不安全的字符编码为安全字符，再进行传输。</p>

<h4 id="url字符集">URL字符集</h4>

<p>默认的计算机系统字符集都倾向于以英文为中心。</p>

<p>通过转义序列,可以用<code>US－AsCII</code>字符集的有限子集对任意字符值或数据进行编码，这样就实现了可移植性和完整性。</p>

<h4 id="编码机制">编码机制</h4>

<p>为了避开安全字符集表示法带来的限制，人们设计了一种编码机制，用来在URL中表示不安全的字符。</p>

<p>通过一种<code>转义</code>表示法来表示不安全的字符。这种转移表示法包含一个百分号（％），后面跟着两个表示字符ASCII码的十六进制数。</p>

<p><img src="http-unicode.png" alt="http unicode" /></p>

<h4 id="字符限制">字符限制</h4>

<p>有些字符不在定义的<code>US－ASCII</code>可打印字符集中，还有些字符会与因特网网关和协议产生混淆，因此不赞成使用。</p>

<p><img src="forbidden-code.png" alt="forbidden code" /></p>

<h3 id="2-5-方案的世界">2.5 方案的世界</h3>

<p><img src="http-scheme1.png" alt="http scheme" /></p>

<p><img src="http-scheme2.png" alt="http scheme" /></p>

<h3 id="2-6-未来展望">2.6 未来展望</h3>

<p>URL有局限性，如果资源的路径搬移了，那么原先的URL便会失效。</p>

<p>URN 基本思想是在搜索资源的过程中引入另一个中间层，通过一个中间资源定位符服务器对资源的实际URL进行登记跟踪。客户端可以定位符请求一个永久的URL。定位符可以以一个资源作为相应。将客户端重定向到当前实际的URL上去。</p>

<h2 id="第三章-http报文">第三章 HTTP报文</h2>

<p>如果说HTTP是因特网的信使，那么HTTP报文就是它用来搬东西的包裹。</p>

<p>主要内容：</p>

<ul>
<li>报文是如何流动的</li>
<li>HTTP报文的三个组成部分（起始行，首部和实体的主体部分）</li>
<li>请求和响应报文之间的区别</li>
<li>请求报文支持的各种功能</li>
<li>和响应报文一起返回的各种状态码</li>
<li>各种各样的HTTP首部都是用来做什么的。</li>
</ul>

<h3 id="3-1-报文流">3.1 报文流</h3>

<p>HTTP报文是在HTTP应用程序之间发送的数据块。这些数据块以一些文本形式的*<code>元信息</code>*开头。这些信息描述了报文的内容和含义，后面跟着可选的数据部分。这些报文在客户端、服务器和代理之间流动。</p>

<h4 id="报文流入源端服务器">报文流入源端服务器</h4>

<p>HTTP使用术语<strong>流入（inbound）</strong>和<strong>流出（outbound）</strong>来描述<strong>事务处理
（transaction）</strong>的方向。
报文流入源端服务器，工作完成后，会流回用户的Agent代理中。</p>

<p><img src="http-message-bound.png" alt="http message bound" /></p>

<h4 id="报文向下游流动">报文向下游流动</h4>

<p>HTTP报文会像河水一样流动。不管是请求报文还是响应报文，所有报文都会像<strong>下游（downstream）</strong>流动。所有报文的发送者都在接收者的<strong>上游（upstream）</strong>。</p>

<h4 id="3-2-报文的组成部分">3.2 报文的组成部分</h4>

<p>HTTP报文是简单的格式化数据块。</p>

<p>每条报文都包含一条来自客户端的请求，或者一条来自服务器的响应。</p>

<p>包含三个部分：起始行，首部，主体</p>

<p>起始行和首部就是由分隔的ASCII文本。每行都以一个由两个字符组成的行终止序列作为结束，其中包含一个回车符和一个换行符。这个行终止序列可以写做CRLF。</p>

<p>实体的主体或报文的主体是一个可选的数据块。与起始行和首部不同的是，主体中可以包含文本或二进制数据，也可以为空。</p>

<p>Content－type说明了主体是什么
Content－Length说明了主体有多大</p>

<h4 id="报文的语法">报文的语法</h4>

<p>分为<strong>请求报文</strong>和<strong>响应报文</strong>。</p>

<ul>
<li>方法（method）
客户端希望服务器对资源执行的动作。是一个单独的词，如GET，POST，HEAD或POST等。</li>
<li>请求URL（request－URL）
命名了说请求资源，活着URL路径组件的完整URL。</li>
<li>版本（version）<br />
报文所使用的HTTP版本。格式类似于：<code>HTTP/&lt;major&gt;.&lt;/minor&gt;</code>。其中版本号（major）和次要版本号（minor）都是整数。</li>
<li>状态码（status－code）<br />
三位数字描述了请求过程中所发生的情况。</li>
<li>原因短语（reason－phrase）
数字状态码的可读版本，包含终止序列之前的所有文本。</li>
<li>首部（header）<br />
可以有零个或多个首部，每个首部都包含一个名字，后面跟着一个冒号（：），然后是一个可选的空格，接着是一个值，最后是一给CRLF。首部是由一个空行（CRLF）结束的。</li>
<li>实体的主体部分（entity－body）<br />
由人意数据组成的数据块。
<br /></li>
</ul>

<p><img src="request-response-demo.png" alt="request response demo" /></p>

<h4 id="3-2-2-起始行">3.2.2 起始行</h4>

<p>所有HTTP报文都以一个起始行做为开始，
请求报文说明了要做些什么
相应报文的起始行说明发生了什么。</p>

<ol>
<li><p>请求行：请求报文的起始行，称为请求行，包含了一个方法和一个请求URL，这个方法描述了服务器应该执行的操作。</p></li>

<li><p>响应行：承载了状态信息和操作产生的所有结果数据，将其返回给客户端。</p></li>

<li><p>方法：告诉服务器做什么事</p></li>

<li><p>状态码：告诉客户端发生了什么</p></li>

<li><p>原因短语：给状态码提供了文本解释</p></li>

<li><p>版本号</p></li>
</ol>

<h4 id="3-2-3-首部">3.2.3 首部</h4>

<p>本质上来说，它们是一些名／值对的列表。</p>

<p>1.首部分类</p>

<ul>
<li>通用首部：既可以出现在请求报文中，也可以出现在响应报文中</li>
<li>请求首部：</li>
<li>响应首部</li>
<li>实体首部：描述主体的长度和内容，或资源的自身</li>
<li>扩展首部</li>
</ul>

<p>2.首部延续行</p>

<p>将长的首部行分为多行，可以提高可读性</p>

<h4 id="3-2-4-实体的主体部分">3.2.4 实体的主体部分</h4>

<h3 id="3-3-方法">3.3 方法</h3>

<p>安全方法：GET方法和HEAD方法被认为是安全的，意味着使用GET或HEAD的方法HTTP请求不会产生什么动作。</p>

<p><strong>HEAD</strong>：在不获取实际资源的情况下，对资源的首部进行检查。</p>

<ul>
<li>了解资源的情况</li>
<li>通过状态码，看看对象是否存在</li>
<li>查看首部，判断资源是否被修改</li>
</ul>

<p><strong>TRACE</strong>：在目的地服务器发起一个“环回”诊断。弹回一条TRACE响应，并在响应主体中携带收到的原始请求报文。这样客户端就可以查看所有中间件HTTP应用程序组成的请求／响应链上，原始报文是否被修改。</p>

<p><strong>OPTIONS</strong>：请求web服务器告知其支持的各种功能。</p>

<p><strong>扩展方法</strong>：常用：lock，mkcol，copy，move等。</p>

  </div>
</div>
<div class="container has-text-centered">
    
</div>

<div class="container has-text-centered">
  
</div>
<section class="section">
  <div class="container has-text-centered">
    <p></p>
  </div>
</section>


